package com.starblink.mine.personhome.ui.follow.ui.followlist.ui

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.starblink.android.basic.animators.FadeInAnimator
import com.starblink.android.basic.base.fragment.BaseTVMFragment
import com.starblink.android.basic.bean.LoadAction
import com.starblink.android.basic.brv.BindingAdapter
import com.starblink.android.basic.brv.PageRefreshLayout
import com.starblink.android.basic.brv.utils.bindingAdapter
import com.starblink.android.basic.brv.utils.linear
import com.starblink.android.basic.brv.utils.models
import com.starblink.android.basic.brv.utils.setup
import com.starblink.android.basic.ext.ApolloValSetExt
import com.starblink.android.basic.ext.visibleOrGone
import com.starblink.android.basic.user.UserRelationCodeEnum
import com.starblink.android.basic.util.ImageUtils
import com.starblink.android.basic.util.post.CommonMutateManage
import com.starblink.android.basic.util.post.PostUtils
import com.starblink.android.basic.modules.mine.MineManager
import com.starblink.android.basic.util.bus.FlowBus
import com.starblink.android.basic.util.bus.FlowConst
import com.starblink.android.basic.util.bus.bean.FollowUserEvent
import com.starblink.basic.log.SKLogger
import com.starblink.basic.util.CommUtils
import com.starblink.basic.util.log.YYLogUtils
import com.starblink.mine.R
import com.starblink.mine.databinding.FragmentFollowListBinding
import com.starblink.mine.databinding.ItemFollowBinding
import com.starblink.mine.personhome.ui.follow.ui.SharedSearchViewModel
import com.starblink.mine.personhome.ui.like.ui.LikeVM
import com.starblink.rocketreserver.SearchAccountsQuery.SearchAccount
import com.starblink.rocketreserver.fragment.AccountF
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

/**
 * 关注列表
 * @note 包含四种状态：
 * 1.已关注用户列表
 * 2.搜索已关注用户列表
 * 3.我的粉丝列表
 * 4.搜索我的粉丝列表
 * @note 4种状态使用同一个接口
 */
class FollowListFragment : BaseTVMFragment<FragmentFollowListBinding, FollowListVM>() {
    private val sharedViewModel by activityViewModels<SharedSearchViewModel>()
    var pageType: Int = PAGE_TYPE_FOLLOWING

    // 客态用户的关注列表或粉丝列表是否允许查看
    var available: Boolean = true

    companion object {
        private const val TAG = "FollowListFragment"
        const val PAGE_TYPE_FOLLOWING = 1 // 关注列表
        const val PAGE_TYPE_FOLLOWERS = 2 // 粉丝列表

        fun newInstance(pageType: Int, accountId: String, available: Boolean = true) =
            FollowListFragment().apply {
                arguments = bundleOf(
                    MineManager.KEY_PAGE_TYPE to pageType,
                    MineManager.KEY_USER_ID to accountId,
                    MineManager.KEY_AVAILABLE to available,
                )
            }
    }

    override fun getViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ): FragmentFollowListBinding {
        return FragmentFollowListBinding.inflate(inflater, container, false)
    }

    override fun initData() {
        arguments?.run {
            pageType = getInt(MineManager.KEY_PAGE_TYPE, PAGE_TYPE_FOLLOWING)
            viewModel.searchScope = pageType
            viewModel.accountId = getString(MineManager.KEY_USER_ID) ?: ""
            available = getBoolean(MineManager.KEY_AVAILABLE, true)
        }
    }

    override fun initView(view: View) {
        super.initView(view)
        // 如果用户不允许查看，仅显示错误提示
        if (!available) {
            viewBinding.page.onError {
                val tvMsg = findViewById<TextView>(R.id.msg2)
                tvMsg.text =
                    "This user has set their ${if (pageType == PAGE_TYPE_FOLLOWING) "Following" else "Followers"}\n list to private."
            }
            viewBinding.page.showError()
            return
        }

        //初始化关注列表
        val bindingAdapter: BindingAdapter.(RecyclerView) -> Unit = {
            addType<SearchAccount, ItemFollowBinding>(it)

            onBind {
                val viewBinding = getBinding<ItemFollowBinding>()
                val accountF = getModel<SearchAccount>().accountF

                ImageUtils.loadImage(
                    context,
                    accountF.headImage ?: "",
                    viewBinding.ivUserHead,
                    ImageUtils.placeholderAvatarImage,
                    ImageUtils.placeholderAvatarImage
                )

                viewBinding.tvUserName.text = accountF.username ?: accountF.userName ?: ""

                viewBinding.tvContent.visibleOrGone(!accountF.description.isNullOrEmpty()) {
                    text = accountF.description
                }

                setFollowState(viewBinding, accountF.relationCode)
            }

            // 点击列表项
            onClick(R.id.root) {
                val accountF = getModel<SearchAccount>().accountF
                MineManager.navigationToOtherUserPersonHome(
                    context,
                    accountF.id,
                    accountF.deleted,
                    accountF.username ?: accountF.userName
                )
            }

            // 点击关注
            onClick(R.id.tv_follow) {
                val accountF = getModel<SearchAccount>().accountF
                val viewBinding = getBinding<ItemFollowBinding>()

                CommonMutateManage.followUser(
                    context,
                    accountF.id,
                    accountF.relationCode,
                    {
                        // 刷新状态
                        setFollowState(
                            viewBinding,
                            if (PostUtils.followed(accountF.relationCode)) accountF.relationCode - 1
                            else accountF.relationCode + 1
                        )
                    })
                { relationCode ->
                    ApolloValSetExt.setApolloVal<AccountF>(
                        accountF,
                        "relationCode",
                        relationCode
                    )
                    setFollowState(viewBinding, relationCode)
                }
            }
        }

        viewBinding.rv.itemAnimator = FadeInAnimator()
        viewBinding.rv.linear().setup(bindingAdapter)

        viewBinding.page.onEmpty {
            val tvMsg = findViewById<TextView>(R.id.msg1)
            tvMsg.text = if (pageType == PAGE_TYPE_FOLLOWING) {
                "Sorry, the following list is empty."
            } else {
                "Sorry, the followers list is empty."
            }
        }

        viewBinding.page.onRefresh {
            viewModel.getFollowList(refresh = true)
        }
        viewBinding.page.onLoadMore {
            viewModel.getFollowList(refresh = false)
        }

        //初始化搜索列表
        viewBinding.rvSearch.itemAnimator = FadeInAnimator()
        viewBinding.rvSearch.linear().setup(bindingAdapter)

        viewBinding.pageSearch.onEmpty {
            val tvMsg = findViewById<TextView>(R.id.msg1)
            tvMsg.text = "Sorry, user not found."
        }

        viewBinding.pageSearch.onRefresh {
            viewModel.getSearchFollowList(refresh = true)
        }
        viewBinding.pageSearch.onLoadMore {
            viewModel.getSearchFollowList(refresh = false)
        }
    }

    private fun setFollowState(viewBinding: ItemFollowBinding, relationCode: Int) {
        when (relationCode) {
            UserRelationCodeEnum.MYSELF.code -> {
                viewBinding.tvFollow.visibleOrGone(false)
            }
            UserRelationCodeEnum.NOTHING.code, UserRelationCodeEnum.FANS.code -> {
                // 我未关注他
                viewBinding.tvFollow.visibleOrGone(true)
                viewBinding.tvFollow.text =
                    CommUtils.getString(com.starblink.basic.style.R.string.add_follow)
                viewBinding.tvFollow.isSelected = false
            }
            UserRelationCodeEnum.FOLLOW.code, UserRelationCodeEnum.BOTH.code -> {
                // 我已关注他
                viewBinding.tvFollow.visibleOrGone(true)
                viewBinding.tvFollow.text =
                    CommUtils.getString(com.starblink.basic.style.R.string.following)
                viewBinding.tvFollow.isSelected = true
            }
        }
    }

    fun handleSearchEvent(sharedFlow: MutableSharedFlow<String>) {
        lifecycleScope.launch {
            sharedFlow
                .flatMapLatest {
//                YYLogUtils.e("Fragment$pageType flatMapLatest $it in thread${Thread.currentThread().name}", "dss")
                    viewModel.searchFollowListFlow(it)
                }
                .flowOn(Dispatchers.IO)
                .catch {
                    // 发生错误无需处理，用户体验更佳
                    YYLogUtils.e("catch $it in thread${Thread.currentThread().name}", "dss")
                }
                .onEach {
                    YYLogUtils.e(
                        "onEach 搜索结果列表显示新列表数据 ${it.size} in thread${Thread.currentThread().name}",
                        "dss"
                    )
                    // 搜索结果列表显示新列表数据
                    viewBinding.pageSearch.index = PageRefreshLayout.startIndex
                    viewBinding.pageSearch.addData(it) {
                        it.size >= LikeVM.PAGE_SIZE
                    }
                }
                .collect()
        }
    }

    override fun startObserve() {
        // 如果用户不允许查看，仅显示错误提示
        if (!available) {
            return
        }
        initFlowEvents()

        if (pageType == PAGE_TYPE_FOLLOWING) {
            // 关注列表搜索事件
            handleSearchEvent(sharedViewModel.searchEventForFollowingList)
        } else {
            // 粉丝列表搜索事件
            handleSearchEvent(sharedViewModel.searchEventForFollowerList)
        }
        viewModel.showSearchResultLiveData.observe(this)
        {
            // 显示或隐藏搜索结果页面
            if (it && viewBinding.pageSearch.visibility == View.GONE) {
                viewBinding.pageSearch.visibleOrGone(true)
                viewBinding.page.visibleOrGone(false)
            } else if (!it && viewBinding.pageSearch.visibility == View.VISIBLE) {
                viewBinding.pageSearch.visibleOrGone(false)
                viewBinding.page.visibleOrGone(true)
            }
        }
        viewModel.listResponseLiveData.observe(this)
        {
            if (viewBinding.rv.models.isNullOrEmpty() || it.refresh) {
                // 刷新或页面销毁恢复
                viewBinding.page.addData(ArrayList(it.totalList)) {
                    it.totalList.size >= viewModel.curPageNo * LikeVM.PAGE_SIZE
                }
            } else {
                // 加载更多
                viewBinding.page.addData(it.pageList) {
                    it.pageList.size >= LikeVM.PAGE_SIZE
                }
            }
        }
        viewModel.searchListResponseLiveData.observe(this)
        {
            if (viewBinding.rvSearch.models.isNullOrEmpty() || it.refresh) {
                // 刷新或页面销毁恢复
                viewBinding.pageSearch.addData(ArrayList(it.totalList)) {
                    it.totalList.size >= viewModel.curPageNo * LikeVM.PAGE_SIZE
                }
            } else {
                // 加载更多
                viewBinding.pageSearch.addData(it.pageList) {
                    it.pageList.size >= LikeVM.PAGE_SIZE
                }
            }
        }
        viewModel.mLoadActionLiveData.observe(this)
        {
            when (it.action) {
                LoadAction.STATE_ERROR -> {
                    if (viewModel.showSearchResultLiveData.value == true) {
                        viewBinding.pageSearch.showError()
                    } else {
                        viewBinding.page.showError()
                    }
                }
            }
        }

        // 直接显示加载中并请求数据
        viewBinding.page.showLoading()
    }

    private fun initFlowEvents() {
        FlowBus.with<FollowUserEvent>(FlowConst.FOLLOW_USER_EVENT).register(this) {
            if(it.id.isNullOrEmpty()) return@register
            SKLogger.e("dss", "FollowListFragment-FOLLOW_USER_EVENT")
            // 关注事件，关注列表 或者 粉丝列表更新状态
            if(viewModel.listResponseLiveData.value != null){
                lifecycleScope.launch {
                    for ((index, searchAccount) in viewModel.listResponseLiveData.value!!.totalList.withIndex()) {
                        val accountF = searchAccount.accountF
                        if (it.id == accountF.id && it.relationCode != accountF.relationCode) {
                            SKLogger.e("dss", "FollowListFragment普通列表发现用户关注状态要修改")
                            ApolloValSetExt.setApolloVal<AccountF>(accountF, "relationCode", it.relationCode)
                            viewBinding.rv.bindingAdapter.notifyItemChanged(index)
                            break
                        }
                    }
                }
            }
            // 如果当前处于搜索状态，搜索列表更新状态
            if (viewModel.showSearchResultLiveData.value == true && viewModel.searchListResponseLiveData.value != null) {
                lifecycleScope.launch {
                    for ((index, searchAccount) in viewModel.searchListResponseLiveData.value!!.totalList.withIndex()) {
                        val accountF = searchAccount.accountF
                        if (it.id == accountF.id && it.relationCode != accountF.relationCode) {
                            SKLogger.e("dss", "FollowListFragment搜索列表发现用户关注状态要修改")
                            ApolloValSetExt.setApolloVal<AccountF>(accountF, "relationCode", it.relationCode)
                            viewBinding.rvSearch.bindingAdapter.notifyItemChanged(index)
                            break
                        }
                    }
                }
            }
        }
    }

    //    // 访问网络进行搜索
//    suspend fun search(key: String): String {
//        YYLogUtils.e("Fragment search ${key} begin in thread${Thread.currentThread().name}", "dss")
//        try {
//            YYLogUtils.e("Fragment ${key}网络查询开启执行", "dss")
//            delay(200)
//            YYLogUtils.e("Fragment ${key}网络查询执行结束", "dss")
//        } catch (e: Exception) {
//            YYLogUtils.e("Fragment ${key}网络查询被取消", "dss")
//        }
//        return "${key}网络查询返回的搜索结果"
//    }
//
//    // 将搜索关键词转换成搜索结果流
//    fun searchFlow(key: String) = flow { emit(search(key)) }
}